<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:test="http://xsltut.googlecode.com"
	xmlns:dot="http://dotml.googlecode.com">
	<xsl:include href="common.xsl"/>
	<xsl:output encoding="UTF-8" method="xml" indent="yes"/>
	<xsl:variable name="targetName" select="/sqlzen/@targetName"/>
	<test:testCase name="schema" inputSchema="${sqlzen-path}/schema/sqlzen.rng" outputSchema="${sqlzen-path}/external/schema/dotml.rng">
		<test:test name="empty">
			<test:input>
				<sqlzen sqlzenVersion="0.1" targetName="test"/>
			</test:input>
			<test:expect>
				<dot:digraph overlap="false" name="ER diagram for test">
					<dot:nodeGlobalAttr fontname="Courier New" fontsize="11" style="filled"/>
				</dot:digraph>
			</test:expect>
		</test:test>
		<test:test name="table">
			<test:input>
				<sqlzen sqlzenVersion="0.1" targetName="test">
					<rule>
						<affixes>
							<dbObjects>
								<table suffix="T"/>
								<primaryKey prefix="IPK_"/>
								<foreignKey prefix="IFK_"/>
							</dbObjects>
							<entitySuffix name="Mst">
								<comment lang="ko" brief="마스터"
								>
									하위 엔티티가 존재하고 하위 엔티티에 대하여 일대다의 형식으로 기본 정보를 관리하는 엔터티 
								</comment>
							</entitySuffix>
							<attributeSuffix name="Seq">
								<comment lang="ko" brief="일련번호"
									>
									특정 Record의 고유 식별을 하기 위한 목적으로 특정 포맷 없이 단순 번호 형태로 부여되는 속성 
								</comment>
							</attributeSuffix>
						</affixes>
					</rule>
					<dictionary>
						<word name="Account">
							<comment lang="ko">유저 어카운트</comment>
						</word>
						<word name="Item">
							<comment lang="ko">아이템</comment>
						</word>
						<tableName>
							<wordRef name="Account"/>
							<entitySuffixRef name="Mst"/>
							<comment lang="ko">어카운트 마스터</comment>
						</tableName>
						<tableName>
							<wordRef name="Item"/>
							<entitySuffixRef name="Mst"/>
							<comment lang="ko">아이템 마스터</comment>
						</tableName>
						<columnName>
							<wordRef name="Account"/>
							<attributeSuffixRef name="Seq"/>
							<comment lang="ko">어카운트 시퀀스</comment>
						</columnName>
						<columnName>
							<wordRef name="Item"/>
							<attributeSuffixRef name="Seq"/>
							<comment lang="ko">아이템 시퀀스</comment>
						</columnName>
					</dictionary>
					<database>
						<table name="AccountMstT">
							<comment lang="ko">어카운트마스터 테이블</comment>
							<columns>
								<column name="AccountSeq" type="integer" notNull="true" autoIncrement="true">
									<comment lang="ko" brief="어카운트PK">
										어카운트 테이블의 Primary Key
									</comment>
								</column>
								<column name="ItemSeq" type="integer" notNull="true">
									<comment lang="ko">
										아이템 외부참조
									</comment>
								</column>
							</columns>
							<constraints>
								<primaryKey column="AccountMstT.AccountSeq"/>
								<foreignKey column="AccountMstT.ItemSeq" referColumn="ItemMstT.ItemSeq" relationName="has"/>
							</constraints>
						</table>
						<table name="ItemMstT">
							<columns>
								<column name="ItemSeq" type="integer" notNull="true" autoIncrement="true">
									<comment lang="ko" brief="아이템PK">
										아이템테이블의 Primary Key
									</comment>
								</column>
							</columns>
							<constraints>
								<primaryKey column="ItemMstT.ItemSeq"/>
							</constraints>
						</table>
					</database>
				</sqlzen>
			</test:input>
			<test:expect>
				<dot:digraph xmlns:dot="http://dotml.googlecode.com" xmlns:test="http://xsltut.googlecode.com" overlap="false"
					name="ER diagram for test">
					<dot:nodeGlobalAttr fontname="Courier New" fontsize="11" style="filled"/>
					<dot:node color="yellowgreen" shape="box" id="AccountMstT" label="Account"/>
					<dot:node shape="ellipse" color="lightgray" fontsize="9" id="id108605" label="AccountSeq" peripheries="2"/>
					<dot:edge arrowhead="none" from="AccountMstT" to="id108605"/>
					<dot:node shape="diamond" color="lightblue" id="id108656" label="has"/>
					<dot:edge from="AccountMstT" to="id108656"/>
					<dot:edge from="id108656" to="ItemMstT"/>
					<dot:node color="yellowgreen" shape="box" id="ItemMstT" label="Item"/>
					<dot:node shape="ellipse" color="lightgray" fontsize="9" id="id108675" label="ItemSeq" peripheries="2"/>
					<dot:edge arrowhead="none" from="ItemMstT" to="id108675"/>
				</dot:digraph>
			</test:expect>
		</test:test>
	</test:testCase>
	<xsl:template match="/">
		<xsl:apply-templates/>
	</xsl:template>
	<xsl:template match="sqlzen">
		<dot:digraph overlap="false">
			<xsl:attribute name="name">
				<xsl:value-of select="concat( 'ER diagram for ', @targetName )"/>
			</xsl:attribute>
			<dot:nodeGlobalAttr fontname="Courier New" fontsize="11" style="filled"/>
			<dot:edgeGlobalAttr arrowsize="0.6" labeldistance="1.5"/>
			<xsl:apply-templates/>
		</dot:digraph>
	</xsl:template>
	<xsl:template match="rule">
		<xsl:apply-templates/>
	</xsl:template>
	<xsl:template match="database">
		<xsl:apply-templates/>
	</xsl:template>
	<xsl:template match="affixes"/>
	<xsl:template match="tags"/>
	<xsl:template match="dictionary"/>
	<xsl:template match="rule">
		<xsl:apply-templates/>
	</xsl:template>
	<xsl:template match="forbiddenWords"/>
	<xsl:template name="putEntityName">
		<xsl:param name="tableName"/>
		<xsl:for-each select="//tableName">
			<xsl:variable name="name">
				<xsl:value-of select="/sqlzen/rule/affixes/dbObjects/table/@prefix"/>
				<xsl:for-each select="entityPrefixRef | wordRef | entitySuffixRef">
					<xsl:value-of select="@name"/>
				</xsl:for-each>
				<xsl:value-of select="/sqlzen/rule/affixes/dbObjects/table/@suffix"/>
			</xsl:variable>
			<xsl:if test="$name = $tableName">
				<xsl:for-each select="wordRef">
					<xsl:value-of select="@name"/>
				</xsl:for-each>
			</xsl:if>
		</xsl:for-each>
	</xsl:template>
	<xsl:template match="relationInfo">
		<xsl:attribute name="shape">diamond</xsl:attribute>
		<xsl:attribute name="color">lightblue</xsl:attribute>
		<xsl:attribute name="peripheries">2</xsl:attribute>
		<xsl:attribute name="label">
			<xsl:value-of select="@name"/>
		</xsl:attribute>
	</xsl:template>
	<xsl:template match="unique"/>
	<xsl:template match="index"/>
	<xsl:template match="table">
		<dot:node>
			<xsl:choose>
				<xsl:when test="relationInfo">
					<xsl:apply-templates select="relationInfo"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:attribute name="shape">box</xsl:attribute>
					<xsl:attribute name="color">yellowgreen</xsl:attribute>
					<xsl:attribute name="label">
						<xsl:call-template name="putEntityName">
							<xsl:with-param name="tableName" select="@name"/>
						</xsl:call-template>
					</xsl:attribute>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:attribute name="id">
				<xsl:value-of select="@name"/>
			</xsl:attribute>
		</dot:node>
		<xsl:apply-templates select="columns"/>
		<!--	Links	-->
		<xsl:for-each select="relationInfo">
			<xsl:variable name="tn" select="../@name"/>
			<dot:edge fontsize="9">
				<xsl:attribute name="from">
					<xsl:value-of select="@from"/>
				</xsl:attribute>
				<xsl:attribute name="to">
					<xsl:value-of select="$tn"/>
				</xsl:attribute>
				<xsl:if test="@fromLabel">
					<xsl:attribute name="headlabel">
						<xsl:value-of select="@fromLabel"/>
					</xsl:attribute>
				</xsl:if>
			</dot:edge>
			<dot:edge fontsize="9">
				<xsl:attribute name="from">
					<xsl:value-of select="$tn"/>
				</xsl:attribute>
				<xsl:attribute name="to">
					<xsl:value-of select="@to"/>
				</xsl:attribute>
				<xsl:if test="@toLabel">
					<xsl:attribute name="taillabel">
						<xsl:value-of select="@toLabel"/>
					</xsl:attribute>
				</xsl:if>
			</dot:edge>
		</xsl:for-each>
		<xsl:for-each select="columns">
			<xsl:variable name="nonForeignColumnCount">
				<xsl:for-each select="column">
					<xsl:variable name="fn" select="concat( ../../@name, '.', @name )"/>
					<xsl:if test="not( ../../constraints/foreignKey[ @column = $fn ] )">1</xsl:if>
				</xsl:for-each>
			</xsl:variable>
			<xsl:if test="string-length( $nonForeignColumnCount ) > 0">
				<xsl:variable name="columnsId" select="generate-id(.)"/>
				<xsl:variable name="tn" select="../@name"/>
				<dot:edge arrowhead="none" style="dotted">
					<xsl:attribute name="from">
						<xsl:value-of select="$tn"/>
					</xsl:attribute>
					<xsl:attribute name="to">
						<xsl:value-of select="$columnsId"/>
					</xsl:attribute>
				</dot:edge>
			</xsl:if>
		</xsl:for-each>
		<xsl:apply-templates select="constraints"/>
	</xsl:template>
	<xsl:template match="index"/>
	<xsl:template match="columns">
		<xsl:variable name="columnsId" select="generate-id(.)"/>
		<xsl:variable name="nonForeignColumnCount">
			<xsl:for-each select="column">
				<xsl:variable name="fn" select="concat( ../../@name, '.', @name )"/>
				<xsl:if test="not( ../../constraints/foreignKey[ @column = $fn ] )">1</xsl:if>
			</xsl:for-each>
		</xsl:variable>
		<xsl:if test="string-length( $nonForeignColumnCount ) > 0">
			<dot:node shape="Mrecord" fontsize="8" height=".3" color="lightgray">
				<xsl:attribute name="id">
					<xsl:value-of select="$columnsId"/>
				</xsl:attribute>
				<xsl:for-each select="column">
					<xsl:variable name="fn" select="concat( ../../@name, '.', @name )"/>
					<xsl:if test="not( ../../constraints/foreignKey[ @column = $fn ] )">
						<dot:row>
							<xsl:attribute name="label">
								<xsl:if test="../../constraints/primaryKey[ @column = $fn ]">*</xsl:if>
								<xsl:value-of select="@name"/>
							</xsl:attribute>
						</dot:row>
					</xsl:if>
				</xsl:for-each>
			</dot:node>
		</xsl:if>
	</xsl:template>
	<xsl:template match="comment"/>
	<xsl:template match="constraints">
		<xsl:apply-templates/>
	</xsl:template>
	<xsl:template match="primaryKey"/>
	<xsl:template match="foreignKey[ @relationName ]">
		<dot:node shape="diamond" color="lightblue">
			<xsl:attribute name="id">
				<xsl:value-of select="generate-id(.)"/>
			</xsl:attribute>
			<xsl:attribute name="label">
				<xsl:value-of select="@relationName"/>
			</xsl:attribute>
		</dot:node>
		<dot:edge>
			<xsl:attribute name="from">
				<xsl:value-of select="../../@name"/>
			</xsl:attribute>
			<xsl:attribute name="to">
				<xsl:value-of select="generate-id(.)"/>
			</xsl:attribute>
		</dot:edge>
		<dot:edge>
			<xsl:attribute name="from">
				<xsl:value-of select="generate-id(.)"/>
			</xsl:attribute>
			<xsl:attribute name="to">
				<xsl:value-of select="substring-before( @referColumn, '.' )"/>
			</xsl:attribute>
		</dot:edge>
	</xsl:template>
	<xsl:template match="foreignKey[ not( @relationName ) ]"/>
	<xsl:template match="*">
		<xsl:text>&#10;</xsl:text>
		<xsl:text>Unmatched element found : '</xsl:text>
		<xsl:value-of select="name(..)"/>
		<xsl:text>/</xsl:text>
		<xsl:value-of select="name()"/>
		<xsl:text>'</xsl:text>
	</xsl:template>
	<xsl:template match="text()"/>
</xsl:stylesheet>
